/**
 * 17/nov/2011 - fabio.melillo@gmail.com
 */
package org.unisannio.remote;

import it.unipr.ce.dsg.s2p.sip.Address;

import java.util.ArrayList;

import org.unisannio.util.ContentRequest;
import org.unisannio.util.Converter;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;

/**
 * This class allows the activity to send all kinds of queries to the target peer selected
 * 
 * @author Fabio Melillo
 *
 */
public class RemoteContentProvider extends GenericRemote {
	
	/**
	 * time before the notification
	 */
	private static long debugTime=20000;

	public RemoteContentProvider(Context context, int port){
		super(context, port);
	}
	
	public RemoteContentProvider(Context context) {
		super(context);
	}
	/**
	 * Synchronous method for querying to the remote device.
	 * Same signature of the local one <a href="http://developer.android.com/reference/android/content/ContentResolver.html#query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String)"> ContentResolver.query()</a>
	 * 
	 * @param contentUri
	 * @param projection
	 * @param where
	 * @param whereArgs
	 * @param sortOrder
	 * @return a Cursor with the results
	 */
	public Cursor query(Uri contentUri, String[] projection, String where, String[] whereArgs, String sortOrder){
		ContentRequest contentReq=new ContentRequest(contentUri, projection, where, whereArgs, sortOrder, null, Converter.QUERY);
 		Object monitor=new Object();
 		broadcastContentPeer.send(contentReq,monitor);
		try {
			synchronized (monitor) {
				monitor.wait(debugTime);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		MatrixCursor cursor=(MatrixCursor) broadcastContentPeer.getCursor();
		return cursor;
	}
	
	
	/**
	 * Synchronous method for insert the ContentValues to the remote device.
	 * Same signature of the local one <a href="http://developer.android.com/reference/android/content/ContentResolver.html#insert(android.net.Uri, android.content.ContentValues)"> ContentResolver.insert()</a>
	 * 
	 * @param contentUri
	 * @param values
	 * @return the Uri of the inserted ContentValues
	 */
	public Uri insert(Uri contentUri, ContentValues values){
		ContentRequest contentReq = new ContentRequest(contentUri, null, null, null, null, values, Converter.INSERT);
		Object monitor=new Object();
		broadcastContentPeer.send(contentReq,monitor);
		synchronized (monitor) {
			try {
				monitor.wait(debugTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		Uri uri=(Uri) broadcastContentPeer.getResultUri();
		return uri;
	}
	
	/**
	 * Synchronous method for delete records from the remote device.
	 * Same signature of the local one <a href="http://developer.android.com/reference/android/content/ContentResolver.html#delete(android.net.Uri, java.lang.String, java.lang.String[])"> ContentResolver.delete()</a>
	 * 
	 * @param contentUri
	 * @param where
	 * @param whereArgs
	 * @return the number of rows affected
	 */
	public int delete(Uri contentUri, String where, String[] whereArgs){
		ContentRequest contentReq = new ContentRequest(contentUri, null, where, whereArgs, null, null, Converter.DELETE);
		Object monitor=new Object();
		broadcastContentPeer.send(contentReq,monitor);
		synchronized (monitor) {
			try {
				monitor.wait(debugTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		int row=broadcastContentPeer.getResultInt();
		return row;
	}
	
	/**
	 * Synchronous method for update the rows of the remote device.
	 * Same signature of the local one <a href="http://developer.android.com/reference/android/content/ContentResolver.html#update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[])"> ContentResolver.update()</a>
	 * 
	 * @param contentUri
	 * @param values
	 * @param where
	 * @param whereArgs
	 * @return the number of rows affected
	 */
	public int update(Uri contentUri, ContentValues values, String where, String[] whereArgs){
		ContentRequest contentReq = new ContentRequest(contentUri, null, where, whereArgs, null, values, Converter.UPDATE);
		Object monitor=new Object();
		broadcastContentPeer.send(contentReq,monitor);
		synchronized (monitor) {
			try {
				monitor.wait(debugTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		int row=broadcastContentPeer.getResultInt();
		return row;
	}
	
	/**
	 * Save the list of address chosen by the user
	 * 
	 * @param destinationList
	 */
	public void saveChosenAddress(ArrayList<Address> destinationList){
		broadcastContentPeer.setDestinationAddress(destinationList);
	}
	/**
	 * Check if there is any address already chosen
	 * 
	 * @return true if there is at least one address set
	 */
	public boolean isChosenAddress(){
		return broadcastContentPeer.isAddressSelected();
	}
	
	/**
	 * Gets the address of all the devices published into the SuperPeer
	 * which have shared the ContentProvider with the interestedUri 
	 * 
	 * @param interestedUri
	 * @return The list of Address of possible targets
	 */
	public ArrayList<Address> retrieveAvailableAddress(String interestedUri){
		return broadcastContentPeer.getTargetAddress(interestedUri);
	}
	
}
